import logging
from common.merchant import handler as merchant_handler
from common.merchant import role_db
from common.merchant.models import RoleLevel, Role
from common.user import db
from common.user.models import User
from django.db import transaction
from common.user.db import encode_password
from common.utils.maestro_exceptions import (
    MaestroException,
    ERROR_USER_NOT_EXISTS,
    ACCESS_DENIED
)

_LOGGER = logging.getLogger(__name__)

RESET_PASSWORD = "123456"


def get_new_role_combination(user_role, old_merchant_role_id, new_merchant_role_id):
    user_role_list = user_role.split(',')[1:-1]
    if old_merchant_role_id:
        user_role_list.remove(str(old_merchant_role_id))
    if new_merchant_role_id and new_merchant_role_id != -1:
        user_role_list.append(str(new_merchant_role_id))
    new_role_combination = ',' + ','.join(user_role_list) + ',' if user_role_list else ''
    return new_role_combination


def get_available_role_id_list(merchant_id, admin_role_id, role_level):
    if role_level == RoleLevel.ROOT.value:
        available_role, _ = role_db.list_role({'merchant_id': merchant_id})
    else:
        available_role, _ = role_db.list_role({'merchant_id': merchant_id, 'supervisor_id': int(admin_role_id)})

    available_role_dct = {role['id']: role['role_name'] for role in available_role}
    available_role_dct.update({-1: '游客账号'})
    return available_role_dct


def update_user_merchant_role(merchant_id, admin_id, user_id, new_role_id, description):
    user_role_level_dct = merchant_handler.get_user_roles_information(user_id)
    admin_role_level_dct = merchant_handler.get_user_roles_information(admin_id)
    admin_merchant_role = admin_role_level_dct['root'] if admin_role_level_dct['root'] \
        else admin_role_level_dct.get(merchant_id)
    admin_merchant_role_id = admin_merchant_role['id'] if admin_role_level_dct['root'] \
        else admin_merchant_role['role_id']
    user = db.get_user(user_id)
    user_merchant_role = user_role_level_dct.get(merchant_id, {}).get('role', {})
    if not user:
        raise MaestroException(ERROR_USER_NOT_EXISTS)
    if not user_merchant_role.get("id"):
        if admin_merchant_role['role_level'] not in [RoleLevel.ROOT.value, RoleLevel.MANAGER.value]:
            raise MaestroException(ACCESS_DENIED)
    elif not admin_merchant_role['role_level'] == RoleLevel.ROOT.value and user_merchant_role['supervisor_id'] != admin_merchant_role_id:
        raise MaestroException(ACCESS_DENIED)
    available_role_dct = get_available_role_id_list(merchant_id, admin_merchant_role_id,
                                                    admin_merchant_role['role_level'])
    role = get_new_role_combination(user.role, user_merchant_role.get("id"), new_role_id)
    with transaction.atomic():
        user.role = role
        user.save()
        if new_role_id not in available_role_dct.keys():
            raise MaestroException(ACCESS_DENIED, '权限不足，无法配置此角色 %s' % available_role_dct.keys())
        if description:
            db.create_or_update_user_description(user_id, merchant_id, admin_id, description)
    return dict()


def reset_user_password(merchant_id, admin_id, user_id):
    user_role_level = merchant_handler.get_user_roles_information(admin_id)
    if user_role_level.get(merchant_id, {}).get('role_level') not in [RoleLevel.ROOT.value,
                                                                      RoleLevel.MANAGER.value]:
        raise MaestroException(ACCESS_DENIED)
    user = User.objects.filter(id=user_id).first()
    user_roles = user.role.strip(",")
    if user_roles:
        user_roles = user_roles.split(",")
        user_role = Role.objects.filter(merchant_id=merchant_id, id__in=user_roles).first()
        if user_role.supervisor_id != user_role_level[merchant_id]['role_id'] and not user_role_level['is_root']:
            raise MaestroException(ACCESS_DENIED)
    else:
        if not user_role_level['is_root']:
            raise MaestroException(ACCESS_DENIED)
    user.password = encode_password(RESET_PASSWORD)
    user.save()
